package br.com.sga.util.conexao;

import br.com.sga.erro.ConexaoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.ArrayBlockingQueue;

/**
 *
 * @author kenzo
 */
public class PoolImpl implements Pool{
    private static Pool instance;
    private DataSource ds;
    private ArrayBlockingQueue<Connection> livres;
    private HashMap<String, Connection> utilizadas;
    private Integer maxConexoes;
    ResourceBundle config;
    
    public static Pool getInstance(){
        if( instance==null ) instance = new PoolImpl();
        return instance;
    }
    
    private PoolImpl(){
        config = ResourceBundle.getBundle("br.com.akeseweb.conexao.banco");
        this.ds = new DataSourcePostgres(config);
        try{
            this.maxConexoes = Integer.parseInt( config.getString("maxConexoes") );
        }catch(MissingResourceException | NumberFormatException e){
            this.maxConexoes = 5;
        }
        this.livres = new ArrayBlockingQueue<>(maxConexoes,true);
        this.utilizadas = new HashMap<>();
    }

    @Override
    public Connection getConnection() throws ConexaoException {
        Connection c = null;
        if( utilizadas.size() < maxConexoes ){
            c = livres.poll();
            if( c == null ){
                c = ds.getConnection();
            } else {
                try {
                    if( c.isClosed() ) this.getConnection();
                } catch (SQLException e) {
                    throw new ConexaoException(e);
                }
            }
            utilizadas.put(c.toString(), c);
        }
        return c;
    }

    @Override
    public void freeConnection(Connection c) throws ConexaoException {
        livres.add(c);
        utilizadas.remove(c.toString());
    }
    
}
